#ifndef ARRAY_H
#define ARRAY_H

#include <stdlib.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_PCRE_H
# include <pcre.h>
#endif
#include "buffer.h"

/*
 * 通用数组
 */
 
/* 定义数据类型的枚举类型 */
typedef enum 
{ 

	TYPE_UNSET, 	/* 数据的类型未设置，这几种数据类型使用了面向对象的设计思想，
					   这个类型相当于父类型 */
	TYPE_STRING, 	/* 字符串类型 */
	TYPE_ARRAY, 	/* 数组类型 */
	TYPE_INTEGER, 	/* 整数类型 */

} data_type_t;

/* 定义UNSET数据类型所包含的数据成员 */
#define DATA_UNSET \
	data_type_t type; \
	buffer *key; \
	int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \
	struct data_unset *(*copy)(const struct data_unset *src); \
	void (* free)(struct data_unset *p); \
	void (* reset)(struct data_unset *p); \
	int (*insert_dup)(struct data_unset *dst, struct data_unset *src); \
	void (*print)(const struct data_unset *p, int depth)
/*
 * 上面的五个函数指针指向各个子数据类型的操作函数。用函数指针模拟虚函数
 */

/* 定义UNSET数据类型，UNSET类 */
typedef struct data_unset 
{
	DATA_UNSET;
} data_unset;

typedef struct 
{
	/* UNSET数据的指针型数组 */
	data_unset **data;
	
	//对数组中的数据索引进行排序。
	size_t *sorted;

	size_t used;
	size_t size;

	size_t unique_ndx; 			//用于产生key。始终是小的未使用的key值。
	size_t next_power_of_2;
} array;


typedef struct 
{
	DATA_UNSET;

	buffer *value;
} data_string;

data_string *data_string_init(void);


typedef struct
{
	DATA_UNSET;
	array *value;
} data_array;

data_array *data_array_init(void);

typedef struct 
{
	DATA_UNSET;
	int value;
} data_integer;

data_integer *data_integer_init(void);

/*
 * 初始化一个数组。
 */
array *array_init(void);
/*
 * 用数组src初始化一个新的数组。
 * 拷贝src中的所有数据到新数组中。
 * 深拷贝。
 */
array *array_init_array(array * src);
/*
 * 释放数组。
 */
void array_free(array * a);
/*
 * 重置数组和数组中的数据。
 */
void array_reset(array * a);
/*
 * 将str插入到数组中。
 * 如果在数据中有和str具有相同key的元素，则替换之。
 * 如果没有，则将str插入数组中，同时，保持sorted数组的有序。
 * 对于string类型数据，将要插入的数据追加到原来的数据中，并以','分割。
 */
int array_insert_unique(array * a, data_unset * str);
/*
 * 返回数组中最后一个数据。
 * 并将数据从数组中删除。
 */
data_unset *array_pop(array * a);
/*
 * 返回数组中第一个未使用的数据。并将这个数据从数组中删除。
 * 如果没有，则返回NULL。 参数t未使用。
 */
data_unset *array_get_unused_element(array * a, data_type_t t);
/*
 * 通过key查找元素。 没有则返回NULL。
 */
data_unset *array_get_element(array * a, const char *key);
/*
 * 使用du替换数组中具有相同key的元素，并返回被替换的元素的指针。
 * 如果不存在key相同的元素，则将du插入数组中。
 */
data_unset *array_replace(array * a, data_unset * du);
/*
 * 返回数组中最长的key的长度。
 */
size_t array_get_max_key_length(array * a);



#endif
